#ifndef RENDERERAPI_H
#define RENDERERAPI_H

#include "Renderer/vertexArray.h"

#include <glm/glm.hpp>

namespace CC
{

	typedef enum
	{
		DisplayModesEnum_NONE = -1,
		DisplayModesEnum_POINTS = 0,
		DisplayModesEnum_LINES,
		DisplayModesEnum_LINE_LOOP,
		DisplayModesEnum_LINE_STRIP,
		DisplayModesEnum_TRIANGLES,
		DisplayModesEnum_TRIANGLE_STRIP,
		DisplayModesEnum_TRIANGLE_FAN
	} DisplayModesEnum;

	typedef enum
	{
		CullFaceEnum_NONE = -1,
		CullFaceEnum_FRONT = 0,
		CullFaceEnum_BACK,
		CullFaceEnum_FRONT_AND_BACK,
	} CullFaceEnum;

	typedef enum
	{
		CapEnum_NONE = -1,
		CapEnum_CULL_FACE = GL_CULL_FACE,
		CapEnum_COLOR_BUFFER_BIT = GL_COLOR_BUFFER_BIT,
		CapEnum_DEPTH_BUFFER_BIT = GL_DEPTH_BUFFER_BIT,
		CapEnum_GL_DEPTH_TEST = GL_DEPTH_TEST,
		CapEnum_GL_DEPTH_TEST_FUNC_LESS = GL_LESS,
		CapEnum_GL_DEPTH_TEST_FUNC_ALWAYS = GL_ALWAYS,
    } CapEnum;

    typedef enum
    {
        DepthFuncEnum_GL_DEPTH_TEST_FUNC_NONE = -1,
        DepthFuncEnum_GL_DEPTH_TEST_FUNC_LESS = GL_LESS,
        DepthFuncEnum_GL_DEPTH_TEST_FUNC_LEQUAL = GL_LEQUAL,
        DepthFuncEnum_GL_DEPTH_TEST_FUNC_ALWAYS = GL_ALWAYS,
    } DepthFuncEnum;

	class RendererAPI
	{
	public:
		enum class API
		{
			None = 0,
			OpenGL = 1
		};

	public:
		virtual ~RendererAPI() = default;

		virtual void Init() = 0;
		virtual void SetViewport(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0;
		virtual void SetClearColor(const glm::vec4 &color) = 0;
		virtual void Clear() = 0;
		virtual void ClearDepth() = 0;
		virtual void Clear(CapEnum bit) = 0;

		virtual void DrawIndexed(const VertexArray *vertexArray, uint32_t indexCount = 0, DisplayModesEnum mode = DisplayModesEnum::DisplayModesEnum_TRIANGLES) = 0;
		virtual void DrawArrays(const VertexArray *vertexArray, uint32_t count = 0, DisplayModesEnum mode = DisplayModesEnum::DisplayModesEnum_TRIANGLES) = 0;
		virtual void DrawLines(const VertexArray *vertexArray, uint32_t vertexCount) = 0;

		virtual void SetLineWidth(float width) = 0;

		virtual void UnBindTexture() = 0;
		virtual void BindTexture(uint32_t slot, uint32_t ID) = 0;
		virtual void CullFace(CullFaceEnum type) = 0;
		virtual void SetEnableState(CapEnum cap, bool enable) = 0;
		virtual void SetDepthFunc(DepthFuncEnum func) = 0;

		static API GetAPI() { return s_API; }
		static RendererAPI *Create();

	private:
		static API s_API;
	};

}

#endif
